#ifndef ARCAM_HPP
#define ARCAM_HPP

#define DEBUG

#include <AR/ar.h>
#include <AR/arMulti.h>
#include <AR/video.h>
#include <AR/gsub_lite.h>
#include <AR/arFilterTransMat.h>
#include <AR2/tracking.h>

#include <time.h>

#include <opencv2/opencv.hpp>


class ArCam
{
public:

    static int setupCamera(const char *cparam_name, char *vconf, ARParamLT **cparamLT_p)
    {
        ARParam			cparam;
        int				xsize, ysize;
        AR_PIXEL_FORMAT pixFormat;

        // Open the video path.
        if (arVideoOpen(vconf) < 0) {
            ARLOGe("setupCamera(): Unable to open connection to camera.\n");
            return (FALSE);
        }

        // Find the size of the window.
        if (arVideoGetSize(&xsize, &ysize) < 0) {
            ARLOGe("setupCamera(): Unable to determine camera frame size.\n");
            arVideoClose();
            return (FALSE);
        }
        ARLOGi("Camera image size (x,y) = (%d,%d)\n", xsize, ysize);

        // Get the format in which the camera is returning pixels.
        pixFormat = arVideoGetPixelFormat();
        if (pixFormat == AR_PIXEL_FORMAT_INVALID) {
            ARLOGe("setupCamera(): Camera is using unsupported pixel format.\n");
            arVideoClose();
            return (FALSE);
        }

        // Load the camera parameters, resize for the window and init.
        if (arParamLoad(cparam_name, 1, &cparam) < 0) {
            ARLOGe("setupCamera(): Error loading parameter file %s for camera.\n", cparam_name);
            arVideoClose();
            return (FALSE);
        }
        if (cparam.xsize != xsize || cparam.ysize != ysize) {
            ARLOGw("*** Camera Parameter resized from %d, %d. ***\n", cparam.xsize, cparam.ysize);
            arParamChangeSize(&cparam, xsize, ysize, &cparam);
        }
#ifdef DEBUG
        ARLOG("*** Camera Parameter ***\n");
        arParamDisp(&cparam);
#endif
        if ((*cparamLT_p = arParamLTCreate(&cparam, AR_PARAM_LT_DEFAULT_OFFSET)) == NULL) {
            ARLOGe("setupCamera(): Error: arParamLTCreate.\n");
            arVideoClose();
            return (FALSE);
        }

        return (TRUE);
    }

public:
    ARParamLT *gCparamLT;

public:
    ArCam()
        : gCparamLT(NULL)
    {

    }

    int Start()
    {

#ifdef DEBUG
    arLogLevel = AR_LOG_LEVEL_DEBUG;
#endif


        //    const char *cparam_name = "c920.dat";char vconf[] = "-width=640 -height=480";
        const char *cparam_name = "8MU2.dat"; char vconf[] = "-width=800 -height=600";
        //    const char *cparam_name = "3MU22.1mm.dat";    char vconf[] = "-width=1280 -height=720";
        if (!setupCamera(cparam_name, vconf, &gCparamLT)) {
            ARLOGe("main(): Unable to set up AR camera.\n");
            exit(-1);
        }

        // Start the video.
        if (arVideoCapStart() != 0) {
            ARLOGe("setupCamera(): Unable to begin camera data capture.\n");
            return (FALSE);
        }
        return TRUE;
    }


    bool read(cv::Mat &m)
    {
        std::cout<<"read\n"<<std::flush;

        AR2VideoBufferT *image;
        // Grab a video frame.
        image = arVideoGetImage();
        if (image && image->fillFlag) {
            m=cv::Mat(600,800,CV_8UC3, image->buff).clone();
            return true;
        }
        return false;
    }


    void End()
    {
        arParamLTFree(&gCparamLT);

        // Camera cleanup.
        arVideoCapStop();
        arVideoClose();
    }


    void test()
    {
        if(Start()==FALSE)
            return;
        int k=0;
        cv::Mat m;
//        while(k!=27)
        for(int i=0;i<100;i++)
        {
            if(read(m))
            {
                cv::imshow("m",m);
//                cv::imwrite("m.png",m);
                k=cv::waitKey(100);
            }
        }
        End();
    }

};


#endif // ARCAM_HPP

